home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / program / wdj0696.zip / CC.ZIP / CC.C next >
C/C++ Source or Header  |  1994-02-02  |  43KB  |  1,300 lines

  1. /*  Note:  this source code is really crappy, but it was written in
  2.  *  a big hurry.
  3.  */
  4.  
  5. /* SS != DS if DLL, fix for bcc and ztc */
  6. /* disabling smart callbacks for bcc and ztc */
  7.  
  8. /*
  9.  *  cc - Vendor-independent interface to C compilers.
  10.  *  
  11.  *  to build me, type "cc -dos -wild cc.c".
  12.  */
  13.  
  14. #include <string.h>
  15. #include <stdlib.h>
  16. #include <stdarg.h>
  17. #include <errno.h>
  18. #include <stdio.h>
  19.  
  20. #include <process.h>
  21. #include <dos.h>
  22.  
  23. int     Version = 0x0009;
  24.  
  25. #if defined(__BORLANDC__)
  26.     #include <io.h>
  27.     #include <fcntl.h>
  28.     #include <sys\stat.h>
  29.     #define WRITE   write
  30.     #define OPEN    open
  31.     #define CLOSE   close
  32.     #define UNLINK  unlink
  33.     #define STRICMP stricmp
  34.     #define CREAT   creat
  35. #elif defined(__ZTC__)
  36.     #include <io.h>
  37.     #define WRITE   write
  38.     int _okbigbuf = 0;  /* makes more memory available */
  39.     #define STRICMP strcmpl
  40.     #define spawnvp(a,b,c) spawnvp(a,b,(const char * const *)c)
  41.     #define execvp(b,c) execvp(b,(const char * const *)c)
  42. #elif defined(_MSC_VER)
  43.     #include <io.h>
  44. /*    #include <sys\stat.h> */
  45. /*    #include <fcntl.h> */
  46.     #define OPEN    open
  47.     #define CLOSE   close
  48.     #define UNLINK  unlink
  49.     #define CREAT   creat
  50.     #define WRITE   _write
  51.     #define STRICMP _stricmp
  52. #endif
  53.  
  54.  
  55. #define TRUE    1
  56. #define FALSE   0
  57.  
  58. const char *Extensions = "c\0cpp\0res\0rc\0def\0obj\0lib\0lib0\0lib1\0\0";
  59. enum { EXT_C=0, EXT_CPP, EXT_RES, EXT_RC, EXT_DEF, EXT_OBJ,
  60.        EXT_LIB, EXT_LIB0, EXT_LIB1, N_EXT };
  61.  
  62. typedef struct  COMPILE_OPTIONS
  63.     {
  64.     int     ProcessorType;  /* 0=8088, 1=80186, etc. */
  65.     int     Align;          /* 1=byte align, 2=word align, etc. */
  66.     int     CompileOnly;    /* TRUE if compile only, no link */
  67.     char    MemoryModel;    /* 't' = tiny, 's' = small, etc. */
  68.     int     SsNeqDs;        /* TRUE if should assume SS != DS */
  69.     int     Windows;        /* TRUE = Windows, FALSE = DOS */
  70.     int     Dll;            /* TRUE = make .dll */
  71.     int     Com;            /* TRUE = make .com (for DOS) */
  72.     int     Debug;          /* 0=no debug, 1=line numbers, 2=all */
  73.     int     StackCheck;     /* TRUE=compile stack checks in */
  74.     int     CPlusPlus;      /* TRUE if using C++ instead of C */
  75.     char    *RunName;       /* Name to use for executable file */
  76.     int     Windows30;      /* TRUE if mark exe/dll for Windows 3.0 */
  77.     int     MapFile;        /* TRUE if we should generate map file */
  78.     int     Verbose;        /* TRUE if we are verbose!  */
  79.     int     WildCards;      /* TRUE if command-line should handle wild-cards */
  80.     char    Prologue;       /* 'a' = AX, 's' = SS, 'd' = DGROUP, '\0' = default */
  81.     int     NoSmart;        /* TRUE if user wants no smart callbacks */
  82.     char   *CodeSegment;    /* name of code segment */
  83.     int     Optimize;       /* zero means no optimize */
  84.     char   *LibName;        /* name of library to update */
  85.     int     Strict;         /* =1  -> user did -DSTRICT
  86.                                =0  -> user did nothing
  87.                                =-1 -> user did -D        */
  88.     }           COMPILE_OPTIONS;
  89.  
  90. enum    COMPILER_TYPE    { MSC, BCC, SC };
  91. typedef void    (*COMPILER_FUNC) (enum COMPILER_TYPE , COMPILE_OPTIONS *);
  92. typedef struct  COMPILER
  93.     {
  94.     char            *CompilerName;
  95.     enum COMPILER_TYPE CompilerType;
  96.     COMPILER_FUNC   CompilerFunc;
  97.     }           COMPILER;
  98.  
  99. void    Msc(enum COMPILER_TYPE, COMPILE_OPTIONS *);
  100. void    Bcc(enum COMPILER_TYPE, COMPILE_OPTIONS *);
  101. void    Ztc(enum COMPILER_TYPE, COMPILE_OPTIONS *);
  102.  
  103. COMPILER    Compilers[] =
  104.     {
  105.         { "msc", MSC, Msc },
  106.         { "bcc", BCC, Bcc },
  107.         { "sc",  SC,  Ztc },
  108.     };
  109. #define     NCOMPILERS  (sizeof(Compilers) / sizeof(COMPILER))
  110.  
  111. #define MAX_FILES   128
  112.  
  113. #define MAX_MACROS   128
  114. int     NMacros;
  115. char    *Macros[MAX_MACROS];
  116.  
  117.  
  118. char    *DefName;
  119. char    CommandLine[128];
  120.  
  121. char    *UsageMessage   =
  122. "cc - Vendor-independent C/C++ Compilation (Windows/DOS Developer's Journal)\0"
  123. "Usage: cc [options] sourcefiles\0"
  124. "\0"
  125. "-1   use 80186 instructions\0"
  126. "-2   use 80286 instructions\0"
  127. "-3   use 80386 instructions\0"
  128. "-4   use 80486 instructions\0"
  129. "-30  mark exe/dll 3.0 compatible\0"
  130. "-a{1|2}  byte or word alignment\0"
  131. "     (default is byte alignment)\0"
  132. "-c   compile only, no link\0"
  133. "-com create .com (DOS only)\0"
  134. "-C   disable smart callbacks\0"
  135. "-d   include complete debug info\0"
  136. "-dl  include line numbers only\0"
  137. "-Dname{=def}  define macro\0"
  138. "-dos compile/link for DOS\0"
  139. "-mx{!}  specify memory model:\0"
  140. "    t = tiny    s = small\0"
  141. "    c = compact m = medium\0"
  142. "    l = large   h = huge\0"
  143. "    ! means assume DS != SS\0"
  144. "      (the default for .dll)\0"
  145. "-M   don't generate map file\0"
  146. "-NT<name>  set name of code segment\0"
  147. "-o<name> set name of target executable\0"
  148. "     name must end in .com, .exe, or .dll\0"
  149. "-O   optimize generated code\0"
  150. "-p   use C++ compiler\0"
  151. "-s   enable stack checks\0"
  152. "-u<libname> Update library with .obj files\0"
  153. "-v   Verbose (don't delete .rsp files)\0"
  154. "-w{e|d}{a|s|d}\0"
  155. "    |    |  (.exe default is SS)\0"
  156. "    |    |  (.dll default is DGROUP)\0"
  157. "    |    +-> a=AX, s=SS, d=DGROUP\0"
  158. "    +-> e=.exe (default), d=.dll\0"
  159. "    default is -we (Windows .exe, use SS)\0"
  160. "-wild link with special wildcard .obj\0"
  161. "\0"
  162. ;
  163.  
  164. #define MAX_ARGS    (64)
  165. int     NCmdArgs    = 1;
  166. char    *CmdArgs[MAX_ARGS];
  167.  
  168.  
  169. #include "common.c"
  170.  
  171. FileType    FilesByExt[N_EXT];
  172.  
  173. FILE    *OpenFile(const char *FileName, const char *Mode)
  174.     {
  175.     FILE    *File;
  176.  
  177.     File    = fopen(FileName, Mode);
  178.     if(File == NULL)
  179.         {
  180.         fprintf(stderr, "Can't open '%s' for %s.\n", FileName,
  181.             (*Mode == 'w') ? "writing" : "reading");
  182.         exit(EXIT_FAILURE);
  183.         }
  184.     return  File;
  185.     }
  186.  
  187. /* GetCompiler() return which vendor's compiler to use. */
  188. COMPILER *GetCompiler(void)
  189.     {
  190.     char    Buffer[64];
  191.     char    *CC;
  192.     int     i;
  193.  
  194.     CC      = getenv("CC");
  195.     if(CC && *CC)
  196.         {
  197.         char    *Output = Buffer;
  198.  
  199.         while(*CC != ' ' && *CC != '\0')
  200.             *Output++   = *CC++ | ' ';    /* lowercase it */
  201.         *Output = '\0';
  202.         while(*CC == ' ')
  203.             ++CC;
  204.         if(*CC)
  205.             CmdArgs[NCmdArgs++]  = CC;
  206.  
  207.         for(i = 0; i < NCOMPILERS; ++i)
  208.             if(!strcmp(Buffer, Compilers[i].CompilerName))
  209.                 return &Compilers[i];
  210.         fprintf(stderr, "'%s': I do not recognize this compiler name "
  211.             "(defined in your\n"
  212.             "   'CC' environment variable. The names I recognize are:\n"
  213.             "    ",
  214.             getenv("CC"));
  215.  
  216.         for(i = 0; i < NCOMPILERS; ++i)
  217.             {
  218.             fprintf(stderr, "'%s'", Compilers[i].CompilerName);
  219.             if(i == (NCOMPILERS-2))
  220.                 fprintf(stderr, " and ");
  221.             else if(i < (NCOMPILERS-1))
  222.                 fprintf(stderr, ", ");
  223.             }
  224.         fprintf(stderr, "\n");
  225.         }
  226.     return 0;
  227.     }
  228.  
  229. void    Usage(void)
  230.     {
  231.     int     NLines;
  232.     char    *Line1, *Line2;
  233.  
  234.     Line1   = UsageMessage;
  235.     while(strlen(Line1))    /* blank line signals start of two-column */
  236.         {
  237.         fprintf(stderr, "%s\n", Line1);
  238.         Line1   += strlen(Line1)+1;
  239.         }
  240.     Line2   = ++Line1;
  241.     for(NLines = 0; strlen(Line2); ++NLines)
  242.         Line2   += strlen(Line2)+1;
  243.     Line2   = Line1;
  244.     NLines /= 2;
  245.     while(NLines-- > 0) /* Count total # of option lines */
  246.         Line2   += strlen(Line2)+1;
  247.     do  {
  248.         int     Column;
  249.  
  250.         
  251.         fprintf(stderr, "  %s", Line1);
  252.         for(Column = strlen(Line1); Column < 36; ++Column)
  253.             fprintf(stderr, " ");
  254.         fprintf(stderr, "%s\n", Line2);
  255.         Line1   += strlen(Line1)+1;
  256.         if(*Line2)
  257.             Line2   += strlen(Line2)+1;
  258.         }   while(*Line2);
  259.     exit(EXIT_FAILURE);
  260.     }
  261.  
  262. void    ErrorOption(char *Arg)
  263.     {
  264.     ErrorOutput("'");
  265.     ErrorOutput(Arg);
  266.     ErrorOutput("': Unknown option\r\n");
  267.     }
  268.  
  269. int Do